﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BZLib.Global;

namespace BZLib
{
    namespace Flags
    {
        public class FlagType
        {
            public readonly string Name;
            public readonly string Abbr;
            public readonly FlagEndurance Endurance;
            public readonly FlagShotType ShotType;
            public readonly FlagQuality Quality;
            public readonly TeamName Team;

            public FlagType() { }

            public FlagType(string name,
                string abbr,
                FlagEndurance endurance,
                FlagShotType shotType,
                FlagQuality quality,
                TeamName team)
            {
                Name = name;
                Abbr = abbr;
                Endurance = endurance;
                ShotType = shotType;
                Quality = quality;
                Team = team;
            }

            public BinaryString Pack()
            {
                BinaryString str = new BinaryString();
                str.PackString(Abbr, 2);
                return str;
            }

            public static BinaryString Unpack(BinaryString str, ref FlagType flag)
            {
                string abbr = str.UnpackString(2);
                flag = FlagList.GetByAbbr(abbr);
                return str;
            }
        }

        public static class FlagList
        {
            public static FlagType Null = new FlagType("", "NullString", FlagEndurance.Normal, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);

            // Team Flags
            public static FlagType RedTeam = new FlagType("Red Team", "R*", FlagEndurance.Normal, FlagShotType.Normal, FlagQuality.Good, TeamName.Red);
            public static FlagType GreenTeam = new FlagType("Green Team", "G*", FlagEndurance.Normal, FlagShotType.Normal, FlagQuality.Good, TeamName.Green);
            public static FlagType BlueTeam = new FlagType("Blue Team", "B*", FlagEndurance.Normal, FlagShotType.Normal, FlagQuality.Good, TeamName.Blue);
            public static FlagType PurpleTeam = new FlagType("Purple Team", "P*", FlagEndurance.Normal, FlagShotType.Normal, FlagQuality.Good, TeamName.Purple);
 
            // Good Flags
            public static FlagType Velocity = new FlagType("High Speed", "V", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType QuickTurn = new FlagType("Quick Turn", "QT", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType OscillationOverthruster = new FlagType("Oscillation Overthruster", "OO", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType RapidFire = new FlagType("Rapid Fire", "F", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType MachineGun = new FlagType("Machine Gun", "MG", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType GuidedMissile = new FlagType("Guided Missile", "GM", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Laser = new FlagType("Laser", "L", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Ricochet = new FlagType("Ricochet", "R", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType SuperBullet = new FlagType("Super Bullet", "SB", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType InvisibleBullet = new FlagType("Invisible Bullet", "IB", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Stealth = new FlagType("Stealth", "ST", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Tiny = new FlagType("Tiny", "T", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Narrow = new FlagType("Narrow", "N", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Shield = new FlagType("Shield", "SH", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Steamroller = new FlagType("Steamroller", "SR", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType ShockWave = new FlagType("Shock Wave", "SW", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType PhantomZone = new FlagType("Phantom Zone", "PZ", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Genocide = new FlagType("Genocide", "G", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Jumping = new FlagType("Jumping", "JP", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Identify = new FlagType("Identify", "ID", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Cloaking = new FlagType("Cloaking", "CL", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Useless = new FlagType("Useless", "US", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Masquerade = new FlagType("Masquerade", "MQ", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Seer = new FlagType("Seer", "SE", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Thief = new FlagType("Thief", "TH", FlagEndurance.Unstable, FlagShotType.Special, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Burrow = new FlagType("Burrow", "BU", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Wings = new FlagType("Wings", "WG", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);
            public static FlagType Agility = new FlagType("Agility", "A", FlagEndurance.Unstable, FlagShotType.Normal, FlagQuality.Good, TeamName.NoTeam);

            // Bad Flags
            public static FlagType ReverseControls = new FlagType("ReverseControls", "RC", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType Colorblindness = new FlagType("Colorblindness", "CB", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType Obesity = new FlagType("Obesity", "O", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType LeftTurnOnly = new FlagType("Left Turn Only", "LT", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType RightTurnOnly = new FlagType("Right Turn Only", "RT", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType ForwardOnly = new FlagType("Forward Only", "FO", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType Jamming = new FlagType("Jamming", "JM", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType NoJumping = new FlagType("No Jumping", "NJ", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType TriggerHappy = new FlagType("Trigger Happy", "TR", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);
            public static FlagType Bouncy = new FlagType("Bouncy", "BY", FlagEndurance.Sticky, FlagShotType.Normal, FlagQuality.Bad, TeamName.NoTeam);

            public static FlagType GetByName(string name)
            {
                return FlagNameDict[name];
            }

            public static FlagType GetByAbbr(string abbr)
            {
                return FlagAbbrDict[abbr];
            }

            private static Dictionary<string, FlagType> FlagNameDict = new Dictionary<string, FlagType>()
            {
                { RedTeam.Name, RedTeam },
                { GreenTeam.Name, GreenTeam },
                { BlueTeam.Name, BlueTeam },
                { PurpleTeam.Name, PurpleTeam },
                { Velocity.Name, Velocity },
                { QuickTurn.Name, QuickTurn },
                { OscillationOverthruster.Name, OscillationOverthruster },
                { RapidFire.Name, RapidFire },
                { MachineGun.Name, MachineGun },
                { GuidedMissile.Name, GuidedMissile },
                { Laser.Name, Laser },
                { Ricochet.Name, Ricochet },
                { SuperBullet.Name, SuperBullet },
                { InvisibleBullet.Name, InvisibleBullet },
                { Stealth.Name, Stealth },
                { Tiny.Name, Tiny },
                { Narrow.Name, Narrow },
                { Shield.Name, Shield },
                { Steamroller.Name, Steamroller },
                { ShockWave.Name, ShockWave },
                { PhantomZone.Name, PhantomZone },
                { Genocide.Name, Genocide },
                { Jumping.Name, Jumping },
                { Identify.Name, Identify },
                { Cloaking.Name, Cloaking },
                { Useless.Name, Useless },
                { Masquerade.Name, Masquerade },
                { Seer.Name, Seer },
                { Thief.Name, Thief },
                { Burrow.Name, Burrow },
                { Wings.Name, Wings },
                { Agility.Name, Agility },
                { ReverseControls.Name, ReverseControls },
                { Colorblindness.Name, Colorblindness },
                { Obesity.Name, Obesity },
                { LeftTurnOnly.Name, LeftTurnOnly },
                { RightTurnOnly.Name, RightTurnOnly },
                { ForwardOnly.Name, ForwardOnly },
                { Jamming.Name, Jamming },
                { NoJumping.Name, NoJumping },
                { TriggerHappy.Name, TriggerHappy },
                { Bouncy.Name, Bouncy }
            };

            private static Dictionary<string, FlagType> FlagAbbrDict = new Dictionary<string, FlagType>()
            {
                { RedTeam.Abbr, RedTeam },
                { GreenTeam.Abbr, GreenTeam },
                { BlueTeam.Abbr, BlueTeam },
                { PurpleTeam.Abbr, PurpleTeam },
                { Velocity.Abbr, Velocity },
                { QuickTurn.Abbr, QuickTurn },
                { OscillationOverthruster.Abbr, OscillationOverthruster },
                { RapidFire.Abbr, RapidFire },
                { MachineGun.Abbr, MachineGun },
                { GuidedMissile.Abbr, GuidedMissile },
                { Laser.Abbr, Laser },
                { Ricochet.Abbr, Ricochet },
                { SuperBullet.Abbr, SuperBullet },
                { InvisibleBullet.Abbr, InvisibleBullet },
                { Stealth.Abbr, Stealth },
                { Tiny.Abbr, Tiny },
                { Narrow.Abbr, Narrow },
                { Shield.Abbr, Shield },
                { Steamroller.Abbr, Steamroller },
                { ShockWave.Abbr, ShockWave },
                { PhantomZone.Abbr, PhantomZone },
                { Genocide.Abbr, Genocide },
                { Jumping.Abbr, Jumping },
                { Identify.Abbr, Identify },
                { Cloaking.Abbr, Cloaking },
                { Useless.Abbr, Useless },
                { Masquerade.Abbr, Masquerade },
                { Seer.Abbr, Seer },
                { Thief.Abbr, Thief },
                { Burrow.Abbr, Burrow },
                { Wings.Abbr, Wings },
                { Agility.Abbr, Agility },
                { ReverseControls.Abbr, ReverseControls },
                { Colorblindness.Abbr, Colorblindness },
                { Obesity.Abbr, Obesity },
                { LeftTurnOnly.Abbr, LeftTurnOnly },
                { RightTurnOnly.Abbr, RightTurnOnly },
                { ForwardOnly.Abbr, ForwardOnly },
                { Jamming.Abbr, Jamming },
                { NoJumping.Abbr, NoJumping },
                { TriggerHappy.Abbr, TriggerHappy },
                { Bouncy.Abbr, Bouncy }
            };
        }
    }
}
